import 'package:casdon/core/logger/log.dart';
import 'package:casdon/modules/recipe/data/model/recipe_search_model.dart';
import 'package:casdon/modules/recipe/domain/states/recipe_search_list_state.dart';
import 'package:casdon/modules/recipe/domain/usecase/recipe_search_list_usecase.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';

class RecipeSearchNotifier
    extends AutoDisposeFamilyAsyncNotifier<RecipeSearchListState, String> {
  late final String name;
  final int pageSize = 20;
  bool _isLoadingMore = false;
  bool _isRefreshing = false;
  bool _hasMore = true;

  bool get hasMore => _hasMore;
  bool get isLoadingMore => _isLoadingMore;
  bool get isRefreshing => _isRefreshing;

  @override
  Future<RecipeSearchListState> build(String arg) async {
    ref.onDispose(() {
      Log.d('RecipeSearchNotifier for $arg 已被释放！');
    });
    final trimArg = arg.trim();
    if (trimArg.isEmpty) {
      return RecipeSearchListState.initial();
    }
    name = trimArg;
    return await _fetchData();
  }

  Future<void> refresh() async {
    if (_isRefreshing) return;
    _isRefreshing = true;
    _hasMore = true;

    try {
      _resetPageNum();
      final result = await _safeFetchData();
      _hasMore = result.data.length >= pageSize;
      state = AsyncValue.data(result);
    } catch (e, st) {
      Log.e("RecipeSearch refresh 错误", e, st);
      state = AsyncValue.error(e, st);
    } finally {
      _isRefreshing = false;
    }
  }

  void _resetPageNum() {
    final currentState = state.valueOrNull;
    if (currentState != null) {
      state = AsyncValue.data(currentState.copyWith(pageNum: 0));
    }
  }

  Future<void> loadMore() async {
    // 如果正在刷新，不要执行加载更多
    if (_isRefreshing || _isLoadingMore || !_hasMore) {
      Log.d(
        'RecipeSearchNotifier loadMore() 被阻止，isRefreshing: $_isRefreshing, isLoadingMore: $_isLoadingMore, hasMore: $_hasMore',
      );
      return;
    }
    _isLoadingMore = true;

    try {
      final currentState = state.valueOrNull;
      if (currentState == null) return;

      final nextPage = await _fetchData();
      final newCount = nextPage.data.length - currentState.data.length;

      if (nextPage.pageNum == currentState.pageNum || newCount <= 0) {
        _hasMore = false;
      } else {
        _hasMore = newCount >= pageSize;
        state = AsyncValue.data(nextPage);
      }
    } catch (e, st) {
      Log.e("RecipeSearch loadMore 错误", e, st);
    } finally {
      _isLoadingMore = false;
    }
  }

  Future<RecipeSearchListState> _fetchData() async {
    RecipeSearchListState? stateData = state.valueOrNull;
    stateData ??= RecipeSearchListState.initial();

    final List<RecipeSearchModel> existingData = List<RecipeSearchModel>.from(
      stateData.data,
    );
    final pageNum = stateData.pageNum + 1;
    final ret = await ref
        .read(recipeSearchListUsecaseProvider)
        .execute(name: name, pageNum: pageNum, pageSize: pageSize);

    if (ret.rows == null || ret.rows!.isEmpty) {
      return stateData;
    }

    final newRecipes = RecipeSearchModel.listFromApi(ret.rows!);
    final mergedData = pageNum == 1
        ? newRecipes
        : [...existingData, ...newRecipes];
    return stateData.copyWith(data: mergedData, pageNum: pageNum);
  }

  Future<void> clearData() async {
    state = AsyncValue.data(RecipeSearchListState.initial());
  }

  Future<RecipeSearchListState> _safeFetchData() async {
    try {
      return await _fetchData();
    } catch (e, st) {
      Log.e("RecipeSearch _safeFetchData 错误", e, st);
      return RecipeSearchListState.initial();
    }
  }
}

final recipeSearchProvider =
    AutoDisposeAsyncNotifierProviderFamily<
      RecipeSearchNotifier,
      RecipeSearchListState,
      String
    >(RecipeSearchNotifier.new);
